#include "edfdatarecord.h"
#include "edfmodel.h"

#include "edfsignaldata.h"

#include <tr1/memory>

namespace biosignal {
namespace edf {

using namespace std;
using namespace std::tr1;

EDFDataRecord::EDFDataRecord(const EDFModel* edf_model, TimePeriod bounds,
                             shared_ptr<const montage::Montage> montage) :
        DataFrame(edf_model, bounds, montage), m_edf_model(edf_model) {

    long bytes_per_data_record = this->m_edf_model->m_bytes_per_data_record;
    long bytes_in_header = this->m_edf_model->m_bytes_in_header;
    TimePeriod tp1 = edf_model->dataframe_time_period(bounds.begin());
    double seconds = (tp1.begin()-edf_model->recording_time().begin()).total_seconds();
    long data_record_id = seconds / edf_model->m_data_record_duration;
    long data_record_init = data_record_id * bytes_per_data_record
                            + bytes_in_header;
    //	std::cout << " =========== datarecord information =======" << std::endl;
    //	std::cout << " data_record_id :" << data_record_id << std::endl;
    //	std::cout << " bytes_in_header :" << bytes_in_header << std::endl;
    //	std::cout << " bytes_per_data_record :" << bytes_per_data_record
    //			<< std::endl;
    //	std::cout << " tellg :" << m_edf_model->biosignal_istream->tellg() << std::endl;
    //	std::cout << " data_record_init :" << data_record_init << std::endl;
    if (m_edf_model->biosignal_istream->tellg() != data_record_init) {
        m_edf_model->biosignal_istream->seekg(data_record_init);
        //		std::cout << " tellg :" << m_edf_model->biosignal_istream->tellg() << std::endl;
    }

    //TODO Fix time in datarecord for edfplus
    TimePoint start = m_edf_model->recording_time().begin()
                      + TimeOffset::Seconds(data_record_id
                                            * m_edf_model->datarecord_duration());
    TimeOffset duration = TimeOffset::Seconds(
                              m_edf_model->datarecord_duration());
    ;
    TimePeriod tp(start, duration);
    m_time_period = tp.insersection(bounds);
    EDFSourceSignal::sample_type num;
    int val = 0;

    SignalsGroup::const_iterator it;
    int i = 0;

    for (it = m_edf_model->signals_group().begin(); it
            != m_edf_model->signals_group().end(); ++it) {
        EDFSourceSignal* si = dynamic_cast<EDFSourceSignal*> (it->get());

        int samples = si->sample_rate()*(m_time_period.duration().total_seconds());
        EDFSignalData* sd = new EDFSignalData(si, samples);

        int skipinisample = (m_time_period.begin() - tp.begin()).total_seconds()*si->sample_rate();
        int skipendsample = (tp.end() - m_time_period.end()).total_seconds()*si->sample_rate();

        add_signaldata(sd);

//         cout << " ======= signal [ " << i << " ] ======= -> "
//              << m_edf_model->biosignal_istream->tellg() << " <- " << endl;
        m_edf_model->biosignal_istream->ignore(skipinisample*2);
        for (int s = 0; s < samples; s++) {
//             std::cout << " tellg : " << m_edf_model->biosignal_istream->tellg()
//                       << " s: " << s << " - ";
            m_edf_model->biosignal_istream->read((char*) &num, 2);
            //			cout << num << " | " ;

            m_signal_data[i]->value(s, num);

            //			if(i==0) {
            //				std::cout << " tellg : " << m_edf_model->biosignal_istream->tellg() << " -  " ;
            //				cout << s << " " << m_signal_data[i]->value( s ) << endl;// << it->physical_dimension() << " - ";
            //			}

        }
        //		if(i==0)
        //			cout << " data record duration : " << m_edf_model->data_record_duration() << endl;
        i++;
        m_edf_model->biosignal_istream->ignore(skipendsample*2);
        //		cout << endl;
    }
//	cout << "------------   finished load edfdatarecord ---------------"
//			<< endl;
}

EDFDataRecord::~EDFDataRecord() {
    //	std::cout << " data_record deleted  id :" << m_data_record_id << std::endl;

}

}
}
